﻿using System;
using Crap4Net;
using Crap4Net.CoverageParsers;
using NUnit.Framework;
using System.Collections.Generic;

namespace Crap4Net.UnitTests.CoverageParsersTests
{

    /// <summary>
    /// Some Limitations of the VSTS Code Coverage:
    /// 1. It doesnt support Generic Methods - at least it doesnt give a proper signature data
    /// 2. Empty classes are just not there - which baiscally is ok.
    /// </summary>


    [TestFixture]
    public class VSCoverageParserTests
    {
        private VSCoverageParser _target;

        [SetUp]
        public void MyTestInitialize()
        {
            _target = new VSCoverageParser();
            _target.LoadData(@"unitTestdata\VSCoverageFiles\DummyProject.coverage");
        }

        [Test]
        [ExpectedException(typeof(ApplicationException))]
        public void Data_FileNotLoaded_ThrowsException()
        {
            var target = new VSCoverageParser();
            var dummy = target.Data;
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void LoadData_InvalidFileName_throwsException()
        {
            var target = new VSCoverageParser();
            target.LoadData("NoSuchFile.xml");
        }

        [Test]
        [Ignore]
        public void LoadData_EmptyClass_ParseOnlyCtor()
        {
            //Empty Classes are just not there
            //nothing to test...
        }

        [Test]
        public void LoadData_CtorMethod_ParseCtor()
        {
            var actual = _target.Data;

            var expected =
                new CoverageDataEntry(
                    new MethodSignature
                        ("DummyProject.dll", "dummyProject", "Class1", ".ctor", new string[] { }), 
                    100);
            CollectionAssert.Contains(actual,expected);
        }

        [Test]
        [Description("Visual studio does nto support generic methods as it should")]
        public void LoadData_GenericMethod_ParsedCorrectly()
        {
            var actual = _target.Data;
            var expected = new CoverageDataEntry(
                    new MethodSignature
                        ("DummyProject.dll", "dummyProject", "Class1", "GenericMethod", new string[] { }),
                    0);
            CollectionAssert.Contains(actual, expected);
        }

        [Test]
        public void LoadData_FullCoverage_CoverageIs100()
        {
            var actual = _target.Data;

            var expected = new CoverageDataEntry(
                new MethodSignature("DummyProject.dll", "dummyProject", "Class1", ".ctor", new string[] { }),
                100);
            CollectionAssert.Contains(actual, expected);

        }

        [Test]
        public void LoadData_NoCoverage_ReturnsZeroCoverage()
        {
            var actual = _target.Data;
            var expected = new CoverageDataEntry(
                new MethodSignature("DummyProject.dll", "dummyProject", "Class1", "staticMethod", new string[] { }),
                0);
            CollectionAssert.Contains(actual, expected);
        }

        [Test]
        public void LoadData_PartialCoverage_CalculateCorrectCoverage()
        {
            var actual = _target.Data;
            var expected = new CoverageDataEntry(
                new MethodSignature("DummyProject.dll", "dummyProject", "Class1", "method1", new string[] { }),
                66);
            CollectionAssert.Contains(actual, expected);
        }

        [Test]
        public void LoadData_Property_returnResultforGetAndSet()
        {
            var actual = _target.Data;

            var expectedGet = new CoverageDataEntry(
                new MethodSignature("DummyProject.dll", "dummyProject", "Class1", "get_SomeProperty", new string[] { }),
                0);
            var expectedSet = new CoverageDataEntry(
                new MethodSignature("DummyProject.dll", "dummyProject", "Class1", "set_SomeProperty", new string[] { "object" }),
                0);
            CollectionAssert.Contains(actual, expectedGet);
            CollectionAssert.Contains(actual, expectedSet);
        }

        [Test]
        public void LoadData_StaticCtor_ParsedCorrectly()
        {
            var actual = _target.Data;
            var expected = new CoverageDataEntry(
                new MethodSignature("DummyProject.dll", "dummyProject", "Class1", ".cctor", new string[] { }),
                100);
            CollectionAssert.Contains(actual, expected);
        }

        [Test]
        public void LoadData_OverloadedMethod_ParseAllInstances()
        {
            var actual = _target.Data;
            var expected = new List<CoverageDataEntry>()
            { 
                new CoverageDataEntry(
                    new MethodSignature("DummyProject.dll", "dummyProject", "Class1", "method2", new string[] { }),
                    0),
                new CoverageDataEntry(
                    new MethodSignature("DummyProject.dll", "dummyProject", "Class1", "method2", new string[] {"int32" }),
                    0),
                new CoverageDataEntry(
                    new MethodSignature("DummyProject.dll", "dummyProject", "Class1", "method2", new string[] { "float32"}),
                    0),
                new CoverageDataEntry(
                    new MethodSignature("DummyProject.dll", "dummyProject", "Class1", "method2", new string[] { "float64"}),
                    0)
            };
            CollectionAssert.IsSubsetOf(expected,actual);
        }

    }
}
